package com.io.压缩20M文件从30秒到1秒的优化过程;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.Pipe;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.concurrent.CompletableFuture;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Test5 {
	
	private static final String ZIP_FILE = "D:/zsl/2.zip";
	private static final String JPG_FILE = "D:/zsl/1.jpg";
	private static final String FILE_NAME = "1.jpg";
	
	public static void zipFileNoBuffer() {
		//开始时间
		long beginTime = System.currentTimeMillis();
	    File zipFile = new File(ZIP_FILE);
	    try (WritableByteChannel out = Channels.newChannel(new FileOutputStream(ZIP_FILE))) {
	    	Pipe pipe = Pipe.open();
	        //异步任务
	        CompletableFuture.runAsync(() -> runTask(pipe));

	        //获取读通道
	        ReadableByteChannel readableByteChannel = pipe.source();
	        ByteBuffer buffer = ByteBuffer.allocate(((int) 1024)*10);
	        while (readableByteChannel.read(buffer) >= 0) {
	            buffer.flip();
	            out.write(buffer);
	            buffer.clear();
	        }
	    } catch (Exception e) {
	        e.printStackTrace();
	    }
	    long endTime = System.currentTimeMillis();
	    System.out.println(endTime - beginTime);
	}
	
	//异步任务
	private static void runTask(Pipe pipe) {
	    try(ZipOutputStream zos = new ZipOutputStream(Channels.newOutputStream(pipe.sink())); WritableByteChannel out = Channels.newChannel(zos)) {
            zos.putNextEntry(new ZipEntry(FILE_NAME));
            FileChannel jpgChannel = new FileInputStream(new File(JPG_FILE)).getChannel();
            jpgChannel.transferTo(0, jpgChannel.size(), out);
            jpgChannel.close();
	    }catch (Exception e){
	        e.printStackTrace();
	    }
	}
	
	public static void main(String[] args) {
		zipFileNoBuffer();
	}

}
